<?php

namespace api\mobile;

use app\common\model\Mobile;
use think\facade\Db;

/**
 * 慧仕.[这家没跑了]
 *
 * 接口文档: https://www.showdoc.com.cn/yxhijinvip/7159718832118146
 * 访问密码：dffd
 */
class Hijin extends BaseModel
{
    private $header = [
        'Content-Type: application/json',
    ];

    /**
     * 创建订单.
     *
     * @params
     * sub_order_id 系统订单号
     * amount 充值金额
     * mobile 充值号码
     *
     * $return  false/供应商订单号
     */
    public function create($order)
    {
        $url = $this->info['url'] . '/api/v1/submitOrder';
        $data = [
            'orderid' => $order['sub_order_id'],
            'phone' => $order['mobile'],
            'product_id' => $this->getProductId($order['mobile'], fen2yuan($order['amount'])),   // 产品id，对应面额
            'callback_url' => $this->notifyUrl,
        ];
        $params = $this->getParams($data);
        $res = curlPost($url, $params, $this->header, 5, true);
        $res = json_decode($res, true);

        $supplier_order_no = '';
        $remark = $res['message'] ?? '下单失败';
        if (!isset($res['code'])) {
            $status = self::NEED_RETRY;
        } else if ($res['code'] == 0) {
            // 0:充值中 1:充值完成 2:充值失败
            switch ($res['data']['status']) {
                case 0:
                    $status = self::SUCCESS;
                    break;
                case 1:
                    $status = self::RECHARGE_SUCCESS;
                    break;
                case 2:
                    $status = self::FAIL;
                    break;
                default:
                    $status = self::NEED_CONFIRM;
                    break;
            }
        } else {
            $status = self::FAIL;
        }

        return compact('status', 'supplier_order_no', 'remark');
    }

    /**
     * 查询余额.
     *
     * 单位：分
     */
    public function queryAmount()
    {
        $url = $this->info['url'] . '/api/v1/queryAccount';
        $params = $this->getParams();
        $res = curlPost($url, $params, $this->header);
        $res = json_decode($res, true);
        if (!isset($res['data']['account'])) {
            $this->error = $res['message'] ?? '查询频繁';

            return false;
        }

        return yuan2fen($res['data']['account']);
    }

    /**
     * 订单查询.
     */
    public function query($data)
    {
        $url = $this->info['url'] . '/api/v1/queryOrder';
        $params = $this->getParams([
            'phone' => $data['mobile'],
            'order_id' => $data['sub_order_id'],
        ]);
        $res = curlPost($url, $params, $this->header);
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 生成签名.
     */
    public function getSign($timestamp)
    {
        return strtolower(md5(strtolower(md5($this->info['app_id'] . $timestamp)) . $this->info['app_secret']));
    }

    /**
     * 获取接口请求参数.
     */
    private function getParams($data = null)
    {
        $timestamp = $this->getMillisecond();
        $params = [
            'timestamp' => $timestamp,
            'sign' => $this->getSign($timestamp),
            'api_key' => $this->info['app_id'],
        ];
        if ($data) {
            $params['data'] = $data;
        }

        return json_encode($params, JSON_UNESCAPED_UNICODE);
    }

    /**
     * 订单回调.
     */
    public function notify($params)
    {
        $insert = [
            'sub_order_id' => $params['data']['orderid'] ?? '',
            'params' => json_encode($params, JSON_UNESCAPED_UNICODE),
            'result' => 'SUCCESS',
        ];

        $sign = $params['sign'] ?? '';
        $checkSign = $this->getSign($params['timestamp']);
        if ($sign !== $checkSign) {
            $insert['result'] = '验签失败';
            Db::name('mobile_notify')->insert($insert);

            return false;
        }

        // 时间不能超过 10 分钟
        $timeDiff = abs($params['timestamp'] - $this->getMillisecond()) / 1000;
        if ($timeDiff > 600) {
            $insert['result'] = '时间戳超时：' . $timeDiff;
            Db::name('mobile_notify')->insert($insert);

            return false;
        }

        $order = Db::name('mobile_order')
            ->where('sub_order_id', $params['data']['orderid'])
            ->where('mobile_supplier_id', $this->info['id'])
            ->find();
        if (empty($order)) {
            $insert['result'] = '订单不存在';
            Db::name('mobile_notify')->insert($insert);

            return false;
        }

        if (in_array($order['supplier_status'], [3, 4, 99])) {
            // if ($order['supplier_status'] == 3) {
            $insert['result'] = '已经成功过';
            Db::name('mobile_notify')->insert($insert);

            return true;
        }

        if ($order['supplier_status'] != 2) {
            $insert['result'] = '订单状态有误：' . $order['supplier_status'];
            Db::name('mobile_notify')->insert($insert);

            return false;
        }

        // 供应商订单状态：1订单未创建 2订单已创建 3充值成功 4充值失败
        // 1:充值成功 2:充值失败
        $supplierStatusMap = [
            1 => 3, // 1已充值 --> 3充值成功
            2 => 99, // 2充值失败 --> 充值失败，等待重试
        ];
        $supplierStatus = $supplierStatusMap[$params['data']['status']] ?? 2;
        if ($order['supplier_status'] == $supplierStatus) {
            Db::name('mobile_notify')->insert($insert);

            return true;
        }
        $update = [
            // 'supplier_order_no' => $params['order_id'],
            'supplier_status' => $supplierStatus,
        ];
        if ($supplierStatus == 99) {
            $order['notify_url'] = '';  // 失败通知先不发
        }
        $update['finish_time'] = time();

        Db::name('mobile_notify')->insert($insert);

        Db::startTrans();
        try {
            // 如果是返佣模式，将订单结算方式改成待结算
            if ($supplierStatus == 3 && $order['settle_type'] == SETTLE_TYPE_PROFIT) {
                if ($order['profit'] == 0) {
                    $update['settle_status'] = 3;
                } elseif ($order['settle_status'] == 1) {
                    $update['settle_status'] = 2;
                }
            }

            Mobile::handleNotify($order, $update);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            $insert['result'] = '订单更新失败' . $order['id'] . '。' . $e->getMessage();
            Db::name('mobile_notify')->insert($insert);

            return false;
        }

        return true;
    }


    /**
     * 当前时间：毫秒.
     */
    public function getMillisecond()
    {
        list($t1, $t2) = explode(' ', microtime());

        return (float) sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }

    /*
     * 根据移动运营商，面额获取产品id
     */
    private function getProductId($mobile, $amount)
    {
        if (!isProd()) {
            return 'TEST_PRODUCT_1';
        }

        $ispType = getMobileIsp($mobile);
        if ($ispType == -1) {
            $ispType = 1;
        }

        $amount = intval($amount);
        $productIdMap = [
            // 移动
            1 => [
                30 => 3,
                50 => 4,
                100 => 5,
                200 => 6,
            ],
            // 联通
            2 => [
                30 => 11,
                50 => 12,
                100 => 13,
                200 => 14,
            ],
            // 电信
            3 => [
                30 => 19,
                50 => 20,
                100 => 21,
                200 => 22,
            ],
        ];

        return $productIdMap[$ispType][$amount] ?? null;
    }
}
